from protocol_mqtt import *
from protocol_multimedia import *
from device_multimedia import *
import paho.mqtt.client as mqtt
import numpy as np
import threading
import logging
import getpass
import json
import time
import wave
import cv2

logging.basicConfig(level=logging.INFO)


class IotDevice(object):
    def __init__(self):
        self.mqttc = MainMQTT()
        self.mms = MultiMediaServer(self.mqttc)
        self.audio = AudioServer()
        self.video = VideoServer()

        self.mqttc.login_ack = self.login_ack
        self.mqttc.login_rej = self.login_rej
        self.mqttc.register_ack = self.register_ack
        self.mqttc.register_rej = self.register_rej
        self.mqttc.onlinelist_update = self.onlinelist_update
        self.mqttc.friendlist_update = self.friendlist_update
        self.mqttc.addf_ack = self.addf_ack
        self.mqttc.addf_rej = self.addf_rej
        self.mqttc.addfriend_to = self.addfriend_to
        self.mqttc.chat_ack = self.chat_ack
        self.mqttc.chat_rej = self.chat_rej
        self.mqttc.usermessage_rec = self.usermessage_rec

        self.mms.audio_on = self.audio_on
        self.mms.audio_off = self.audio_off

        self.mms.video_on = self.video_on
        self.mms.video_off = self.video_off

        self.terminate = False

    #########################################
    ###                函数                ###
    #########################################

    def start(self):
        try:
            res = self.mqttc.connect_server(addr="10.102.24.227")
            if res == 0:
                self.login()
            else:
                raise ValueError
        except:
            logging.info("Failed to connect mqtt server.")
            logging.info("Device shutting down...")
            self.terminate = True
        finally:
            while not self.terminate:
                time.sleep(1)

    def login(self, type=True):
        if type:
            try:
                user_id, user_pwd = self.load_login_info()
            except:
                logging.info("Auto login failed. Please login manually.")
                user_id, user_pwd = self.save_login_info()
        else:
            user_id, user_pwd = self.save_login_info()
        self.mqttc.login(user_id, user_pwd)

    def load_login_info(self):
        with open("iot_login_info.json") as f:
            device_data = json.load(f)
        return device_data['user_id'], device_data['user_pwd']

    def save_login_info(self):
        device_data = {}
        device_data['user_id'] = input("Userid:")
        device_data['user_pwd'] = getpass.getpass()
        with open("iot_login_info.json", 'w') as f:
            f.write(json.dumps(device_data))
        return device_data['user_id'], device_data['user_pwd']

    #########################################
    ###                回调                ###
    #########################################

    def login_ack(self, user_id, session):
        logging.info("Loggedin:\tid:\t" + user_id + "\tsession:\t" + session)

    def login_rej(self):
        logging.info(
            "Login failed. 'R' to register new account. 'Q' to exit. Any other key to retry")
        cmd = input()
        if cmd == "Q" or cmd == "q":
            self.terminate = True
        elif cmd == "R" or cmd == "r":
            logging.info("Register")
            user_name = input("Username:")
            user_pwd = getpass.getpass()
            self.mqttc.register(user_name, user_pwd)
        else:
            self.login(type=False)

    def register_ack(self, user_id):
        logging.info("Sucessfully registed:" + str(user_id))
        self.login(type=False)

    def register_rej():
        logging.info("Register failed. Q to exit. Any other key to retry")
        cmd = Input()
        if cmd == "Q" | cmd == "q":
            self.terminate = True
            return
        else:
            logging.info("Register")
            user_name = input("Username:")
            user_pwd = getpass.getpass()
            self.mc.registe(user_name, user_pwd)

    def addfriend_to(self, data):
        logging.debug("Addfriend request received:%s" % data[0])
        self.mqttc.addfriend(data[0])

    def addf_ack(self):
        logging.debug("Addfriend request send successful.")

    def addf_rej(self):
        logging.debug("Addfriend request send failed.")

    def onlinelist_update(self, data):
        pass

    def friendlist_update(self, data):
        pass

    def chat_ack(self):
        pass

    def chat_rej(self):
        pass

    def usermessage_rec(self, message):
        self.mms.on_message(message)

    def audio_on(self, data):
        logging.debug("audio on received")
        self.audio.topic = "/" + data['user_id'] + \
            "/" + data['session'] + "/" + data['channel']
        self.audio.start(self.mqttc)


    def audio_off(self, data):
        logging.debug("audio off received")
        self.audio.stop()

    def video_on(self, data):
        logging.debug("video on received")
        self.video.topic = "/" + data['user_id'] + \
            "/" + data['session'] + "/" + data['channel']
        self.video.start(self.mqttc)


    def video_off(self, data):
        logging.debug("video off received")
        self.video.stop()


iot = IotDevice()
iot.start()
